<template>
  <div class="">
    <div>
      <div class="w-100 ib" @click="() => getParent()">parent click</div>
      <el-select v-model="pvalue" @change="getParent" placeholder="parent data">
        <el-option
          v-for="item in parentOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value">
        </el-option>
      </el-select>
    </div>
    <!-- Vue2.2.0新增API -->
    <!-- 
      以允许一个祖先组件向其所有子孙后代注入一个依赖，
      不论组件层次有多深，并在起上下游关系成立的时间里始终生效。
      =>
      祖先组件中通过provider来提供变量，在子孙组件中通过inject来注入变量。
      provide / inject API 
        api参照  => 实现了react的context的功能
        主要解决 => 跨级组件间的通信问题
        使用场景 => 子组件获取上级组件的状态，
                    跨级组件间建立了一种主动提供与依赖注入的关系
        比emitter优雅的多的机制
     -->
    <Son :sonOptions="parentOptions" />
  </div>
</template>
 
<script>
// provide 和 inject 绑定并不是可响应的。
// 这是刻意为之的。然而，如果你传入了一个可监听的对象，那么其对象的属性还是可响应的
// provide与inject => 实现数据响应式 (两种解决方案)
// 1. provide祖先组件的实例，然后在子孙组件中注入依赖
//     缺点=> 这个实例上挂载很多没有必要的东西比如props，methods
// 2. vue2.6最新API Vue.observable 优化响应式 provide(推荐)
// import Son from './son'
import Vue from 'vue'
const Son = () => import('./son')
export default {
  name: 'attrsListeners',
  components: { Son },
  data () {
    return {
      parentOptions: [
        {value: '选项1', label: 'label1'},
        {value: '选项2', label: 'label2'},
        {value: '选项3', label: 'label3'}
      ],
      pvalue: '选项2'
    }
  },
  // provide() {
  //   return {
  //     selectValue: this.pvalue //方法一：提供祖先组件的实例
  //   };
  // },
  // provide: {
  //   selectValue: '选项2'
  // },
  // 方法二:使用2.6最新API Vue.observable 优化响应式 provide
  provide() {
    this.selectValue = Vue.observable({
      pvalue: this.pvalue
    });
    return {
      selectValue: this.selectValue
    };
  },
  watch: {
    pvalue(v) {
      // console.log(v)
      // 法一 在子组件 监听无效
      // this.selectValue = v
      // 法二 在子组件 监听有效
      this.selectValue.pvalue = v
    }
  },
  methods: {
    getParent(v) {
      // console.log(v)
      // this.selectValue.color = v;
      this.value = v
    },
  },
}
</script>
 
<style scoped lang="less">
 
</style>